package com.authentication.center.system.security;

import com.authentication.center.mapper.AppRoleMapper;
import com.authentication.center.mapper.AppUserMapper;
import com.authentication.center.model.AppRole;
import com.authentication.center.model.AppUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author : garvin
 * @version V1.0
 * @date : 2020年10月14日 17:12
 */
@Slf4j
@Component
public class UserDetailsServiceImpl implements UserDetailsService {

    private PasswordEncoder passwordEncoder;
    private AppUserMapper appUserMapper;
    private AppRoleMapper appRoleMapper;

    public UserDetailsServiceImpl(PasswordEncoder passwordEncoder, AppUserMapper appUserMapper, AppRoleMapper appRoleMapper) {
        this.passwordEncoder = passwordEncoder;
        this.appUserMapper = appUserMapper;
        this.appRoleMapper = appRoleMapper;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        log.info("username is:" + username);

        AppUser appUser = new AppUser();
        appUser.setUsername(username);
        AppUser user = appUserMapper.selectOne(appUser);
        if (Objects.isNull(user)) {
            throw new UsernameNotFoundException("the user is not found " + username);
        }

        List<AppRole> appRoles = appRoleMapper.selectRolesByUserId(user.getId());
        List<SimpleGrantedAuthority> authorities = appRoles.stream().map(role -> new SimpleGrantedAuthority(role.getRole())).collect(Collectors.toList());

        // 线上环境应该通过用户名查询数据库获取加密后的密码
        String password = passwordEncoder.encode(user.getPassword());
        return new org.springframework.security.core.userdetails.User(username, password, authorities);
    }
}
